import { isObject, hasChanged } from "../utils/index";
import { createDep } from "./dep";
import { ReactiveEffect } from "./effect";
import { trackEffect, triggerEffect } from "./effect";

export function computed(fn) {
  return new ComuputedImpl(fn);
}

export class ComuputedImpl {
  deps;
  __v_isComputed = true;
  constructor(fn) {
    if (typeof fn === "function") {
      this.getter = fn;
    } else {
      this.getter = fn.get;
      this.setter = fn.set;
    }
    this._effect = new ReactiveEffect(this.getter);
    this.deps = createDep();
  }
  get value() {
    // 如果没有setter, 那么不需要追踪, 因为不会被主动改变
    if (this.setter) {
      trackComputed(this);
    }

    const res = this._effect.run();

    return res;
  }

  set value(newValue) {
    if (this.setter) {
      this.setter(newValue);
      triggerComputed(this);
    }
  }
}

function trackComputed(target) {
  trackEffect(target.deps);
}

function triggerComputed(target) {
  triggerEffect(target.deps);
}
